/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 bitmap_layer.h

	$Header: /resource_editor/bitmap_layer.h $

	$NoKeywords: $

 ************************************************************************/
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "bitmap_raw.h"
#include "convert_16_bit.h"
#include "progress_handler.h"
#include "pixel_24.h"

//t_bitmap_raw_24 class loads and saves raw 24bit bitmaps.

char const t_resource_traits<t_bitmap_raw_24>::prefix[] = "bitmap_raw";

char const t_resource_traits<t_bitmap_raw_24>::extension[] = "tga";

namespace {

	unsigned short k_bitmap_24_version = 1;
};

// Constructors / Destructor
t_bitmap_raw_24::t_bitmap_raw_24()
{

}

t_bitmap_raw_24::~t_bitmap_raw_24()
{

}

// Member functions	
bool t_bitmap_raw_24::read( std::streambuf& buffer, t_progress_handler* handler )
{	
	int version			= get<t_int32>( buffer );
	int height			= get<t_int32>( buffer );
	int width			= get<t_int32>( buffer );
	int data_size		= get<t_int32>( buffer );

	t_pixel_24* data = get_data_ptr();
	
	delete [] data;
	
	t_pixel_24* new_data = new t_pixel_24[width * height];

	buffer.sgetn(reinterpret_cast<char*>(new_data), data_size);
	
	t_abstract_bitmap24::init( width, height, width * sizeof(t_pixel_24), new_data );
	
	return true;
}

bool t_bitmap_raw_24::write( std::streambuf& buffer ) const
{
	int height		= t_abstract_bitmap24::get_height();
	int width		= t_abstract_bitmap24::get_width();
	int data_size	= height*width*sizeof(t_pixel_24);

	put<t_int32>( buffer, k_bitmap_24_version );
	put<t_int32>( buffer, height );
	put<t_int32>( buffer, width );
	put<t_int32>( buffer, data_size );
	
	t_pixel_24 const* data = get_data_ptr();
	
	buffer.sputn(reinterpret_cast<char const*>(data), data_size);
	
	return true;
}

bool t_bitmap_raw_24::init(int width, int height, t_memory_bitmap32 & source_bitmap)
{
	//copy the copy_data into the new_data

	if (height <= 0 || width <= 0)
		return false;
			
	t_memory_bitmap24::init( width, height );

	t_pixel_32 const* source_ptr	= source_bitmap.advance_line( source_bitmap.get_data_ptr(), 0 );
	t_pixel_24*		  dest_ptr		= advance_line( get_data_ptr(), 0 );

	while (height--)
	{
		int current_width	= 0;

		while(current_width < width)
		{
			dest_ptr[current_width].red		= source_ptr[current_width].red;
			dest_ptr[current_width].green	= source_ptr[current_width].green;
			dest_ptr[current_width].blue	= source_ptr[current_width].blue;
			current_width++;
		}
		
		source_ptr = source_bitmap.advance_line( source_ptr );
		dest_ptr   = advance_line( dest_ptr );
	}

	return true;
}


////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////

t_bitmap_raw_16::t_bitmap_raw_16(){}

t_bitmap_raw_16::t_bitmap_raw_16( t_bitmap_raw_24 const& source )
{
	int width	= source.get_width();
	int height	= source.get_height();

	//copy the copy_data into the new_data buffer, converting from 24 -> 16 bit

	if (height <= 0 || width <= 0)
		return;
	
	t_memory_bitmap16::init( width, height );

	t_pixel_24 const* source_ptr	= source.advance_line( source.get_data_ptr(), 0 );
	t_uint16*		  dest_ptr		= advance_line( get_data_ptr(), 0 );

	while (height--)
	{
		int current_width	= 0;
		
		while(current_width < width)
		{
			dest_ptr[current_width]	= convert_to_16_bit(
				source_ptr[current_width].red, 
				source_ptr[current_width].green, 
				source_ptr[current_width].blue 
				);
		
			current_width++;
		}
		
		source_ptr = source.advance_line( source_ptr );
		dest_ptr   = advance_line( dest_ptr );
	}
}

t_bitmap_raw_16::~t_bitmap_raw_16(){}
 
// --------------------------------------------------------
// draws to the given surface
// --------------------------------------------------------
void	t_bitmap_raw_16::draw_to( t_screen_rect source_rect, t_abstract_bitmap16& dest,
                                          t_screen_point dest_point ) const
{
	::draw( dest, dest_point, *this, source_rect );
}
